﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
using System.Windows.Data;

namespace NczControlLibrary.Controls {
    [TemplatePart(Name = "ArrowsPanel",Type = typeof(StackPanel)),
    TemplatePart(Name = "ContentPanel",Type = typeof(StackPanel))]
    public class OarButton : Control {
        public enum OarMode {
            info, button, infobutton
        }
        enum Vs {
            infoover,
            infoleave,
            infodown,
            infoup,
            infonormal,
            infolpover,
            infolpleave,
            infolpdown,
            infolpup,
            buttonover,
            buttonleave,
            buttondown,
            buttonup,
            buttonnormal,
            buttonlpover,
            buttonlpleave,
            buttonlpdown,
            buttonlpup,
            infobuttonover,
            infobuttonleave,
            infobuttondown,
            infobuttonup,
            infobuttonnormal,
            infobuttonlpover,
            infobuttonlpleave,
            infobuttonlpdown,
            infobuttonlpup
        }
        enum State {
            ap_enter, ap_leave, ap_down, ap_up, cp_enter, cp_leave, cp_down, cp_up,
        }
        public OarButton() {
            base.DefaultStyleKey = typeof(OarButton);
        }
        StackPanel cp,ap;
        public override void OnApplyTemplate() {
            this.cp = this.GetTemplateChild("ContentPanel") as StackPanel;
            this.ap = this.GetTemplateChild("ArrowsPanel") as StackPanel;
            this.cp.MouseEnter += new MouseEventHandler(cp_MouseEnter);
            this.cp.MouseLeave += new MouseEventHandler(cp_MouseLeave);
            this.cp.MouseLeftButtonDown += new MouseButtonEventHandler(cp_MouseLeftButtonDown);
            this.cp.MouseLeftButtonUp += new MouseButtonEventHandler(cp_MouseLeftButtonUp);

            this.ap.MouseEnter += new MouseEventHandler(ap_MouseEnter);
            this.ap.MouseLeave += new MouseEventHandler(ap_MouseLeave);
            this.ap.MouseLeftButtonDown += new MouseButtonEventHandler(ap_MouseLeftButtonDown);
            this.ap.MouseLeftButtonUp += new MouseButtonEventHandler(ap_MouseLeftButtonUp);
            base.OnApplyTemplate();
        }
        #region MyRegion
        void cp_MouseLeftButtonUp(object sender,MouseButtonEventArgs e) {
            this.RunEffect(State.cp_up,this.Mode);
        }

        void cp_MouseLeftButtonDown(object sender,MouseButtonEventArgs e) {
            this.RunEffect(State.cp_down,this.Mode);
        }

        void cp_MouseLeave(object sender,MouseEventArgs e) {
            this.RunEffect(State.cp_leave,this.Mode);
        }

        void cp_MouseEnter(object sender,MouseEventArgs e) {
            this.RunEffect(State.cp_enter,this.Mode);
        }
        void ap_MouseLeftButtonUp(object sender,MouseButtonEventArgs e) {
            this.RunEffect(State.ap_up,this.Mode);
        }

        void ap_MouseLeftButtonDown(object sender,MouseButtonEventArgs e) {
            this.RunEffect(State.ap_down,this.Mode);
        }

        void ap_MouseLeave(object sender,MouseEventArgs e) {
            this.RunEffect(State.ap_leave,this.Mode);
        }

        void ap_MouseEnter(object sender,MouseEventArgs e) {
            this.RunEffect(State.ap_enter,this.Mode);
        }
        #endregion
        public event RoutedEventHandler eClick;
        void OneClick() {
            if (this.eClick != null) {
                this.eClick.Invoke(this,null);
            }
        }
        #region dependency properties
        public static readonly DependencyProperty HorizontalOffsetProperty = DependencyProperty.Register("HorizontalOffset",typeof(double),typeof(OarButton),new PropertyMetadata(5.0d,
(o,k) => { }));
        public double HorizontalOffset { get { return (double)this.GetValue(HorizontalOffsetProperty); } set { this.SetValue(HorizontalOffsetProperty,value); } }
        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text",typeof(string),typeof(OarButton),new PropertyMetadata("oar button",
(o,k) => { }));
        public string Text { get { return (string)this.GetValue(TextProperty); } set { this.SetValue(TextProperty,value); } }
        public static readonly DependencyProperty InfoBackgroundProperty = DependencyProperty.Register("InfoBackground",typeof(Brush),typeof(OarButton),new PropertyMetadata(
(o,k) => { }));
        public Brush InfoBackground { get { return (Brush)this.GetValue(InfoBackgroundProperty); } set { this.SetValue(InfoBackgroundProperty,value); } }
        public static readonly DependencyProperty InfoWidthProperty = DependencyProperty.Register("InfoWidth",typeof(double),typeof(OarButton),new PropertyMetadata(5d,
(o,k) => { }));
        public double InfoWidth { get { return (double)this.GetValue(InfoWidthProperty); } set { this.SetValue(InfoWidthProperty,value); } }
        public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data",typeof(Geometry),typeof(OarButton),new PropertyMetadata(
(o,k) => { }));
        public Geometry Data { get { return (Geometry)this.GetValue(DataProperty); } set { this.SetValue(DataProperty,value); } }
        public static readonly DependencyProperty StrokeThicknessProperty = DependencyProperty.Register("StrokeThickness",typeof(double),typeof(OarButton),new PropertyMetadata(
(o,k) => { }));
        public double StrokeThickness { get { return (double)this.GetValue(StrokeThicknessProperty); } set { this.SetValue(StrokeThicknessProperty,value); } }
        public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register("Stroke",typeof(Brush),typeof(OarButton),new PropertyMetadata(
(o,k) => { }));
        public Brush Stroke { get { return (Brush)this.GetValue(StrokeProperty); } set { this.SetValue(StrokeProperty,value); } }
        public static readonly DependencyProperty FillProperty = DependencyProperty.Register("Fill",typeof(Brush),typeof(OarButton),new PropertyMetadata(
(o,k) => { }));
        public Brush Fill { get { return (Brush)this.GetValue(FillProperty); } set { this.SetValue(FillProperty,value); } }
        public static readonly DependencyProperty InfoSizeProperty = DependencyProperty.Register("InfoSize",typeof(double),typeof(OarButton),new PropertyMetadata(11.2d,
(o,k) => { }));
        public double InfoSize { get { return (double)this.GetValue(InfoSizeProperty); } set { this.SetValue(InfoSizeProperty,value); } }
        public static readonly DependencyProperty InfoProperty = DependencyProperty.Register("Info",typeof(string),typeof(OarButton),new PropertyMetadata("_",
(o,k) => { }));
        public string Info { get { return (string)this.GetValue(InfoProperty); } set { this.SetValue(InfoProperty,value); } }
        public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius",typeof(CornerRadius),typeof(OarButton),new PropertyMetadata(
(o,k) => { }));
        public CornerRadius CornerRadius { get { return (CornerRadius)this.GetValue(CornerRadiusProperty); } set { this.SetValue(CornerRadiusProperty,value); } }
        public static readonly DependencyProperty InfoPictureProperty = DependencyProperty.Register("InfoPicture",typeof(BitmapImage),typeof(OarButton),new PropertyMetadata(
(o,k) => { }));
        public BitmapImage InfoPicture { get { return (BitmapImage)this.GetValue(InfoPictureProperty); } set { this.SetValue(InfoPictureProperty,value); } }
        #endregion
        public OarMode Mode { get; set; }
        bool mark = true;
        private void RunEffect(State state,OarMode oarMode) {
            switch (oarMode) {
                case OarMode.info:
                switch (state) {
                    case State.ap_enter:
                    //VisualStateManager.GoToState(this,Vs.infolpover.ToString(),false);
                    break;
                    case State.ap_leave:
                    //VisualStateManager.GoToState(this,Vs.infolpleave.ToString(),false);
                    break;
                    case State.ap_down:
                    if (mark)
                        VisualStateManager.GoToState(this,Vs.infodown.ToString(),false);
                    else
                        VisualStateManager.GoToState(this,Vs.infolpdown.ToString(),false);
                    this.mark = !this.mark;
                    break;
                    case State.ap_up:
                    //VisualStateManager.GoToState(this,Vs.infolpup.ToString(),false);
                    break;
                    case State.cp_enter:
                    //VisualStateManager.GoToState(this,Vs.infoover.ToString(),false);
                    break;
                    case State.cp_leave:
                    //VisualStateManager.GoToState(this,Vs.infoleave.ToString(),false);
                    break;
                    case State.cp_down:
                    if (mark)
                        VisualStateManager.GoToState(this,Vs.infodown.ToString(),false);
                    else
                        VisualStateManager.GoToState(this,Vs.infolpdown.ToString(),false);
                    this.mark = !this.mark;
                    break;
                    case State.cp_up:
                    //VisualStateManager.GoToState(this,Vs.infoup.ToString(),false);
                    break;
                    default:
                    break;
                }
                break;
                case OarMode.button:
                switch (state) {
                    case State.ap_enter:
                    //VisualStateManager.GoToState(this,Vs.buttonlpover.ToString(),false);
                    break;
                    case State.ap_leave:
                    //VisualStateManager.GoToState(this,Vs.buttonlpleave.ToString(),false);
                    break;
                    case State.ap_down:
                    var b = this.ap.Children[1] as Border;
                    var path = b.Child as Path;
                    if (path.FlowDirection == System.Windows.FlowDirection.LeftToRight)
                        VisualStateManager.GoToState(this,Vs.buttonlpdown.ToString(),false);
                    else
                        VisualStateManager.GoToState(this,Vs.buttonlpleave.ToString(),false);
                    break;
                    case State.ap_up:
                    //VisualStateManager.GoToState(this,Vs.buttonlpup.ToString(),false);
                    break;
                    case State.cp_enter:
                    //VisualStateManager.GoToState(this,Vs.buttonover.ToString(),false);
                    break;
                    case State.cp_leave:
                    //VisualStateManager.GoToState(this,Vs.buttonleave.ToString(),false);
                    break;
                    case State.cp_down:
                    VisualStateManager.GoToState(this,Vs.buttondown.ToString(),false);
                    break;
                    case State.cp_up:
                    this.OneClick();
                    VisualStateManager.GoToState(this,Vs.buttonup.ToString(),false);
                    break;
                    default:
                    break;
                }
                break;
                case OarMode.infobutton:
                switch (state) {
                    case State.ap_enter:
                    VisualStateManager.GoToState(this,Vs.infobuttonlpover.ToString(),false);
                    break;
                    case State.ap_leave:
                    //VisualStateManager.GoToState(this,Vs.infobuttonlpleave.ToString(),false);
                    break;
                    case State.ap_down:
                    VisualStateManager.GoToState(this,Vs.infobuttonlpdown.ToString(),false);
                    break;
                    case State.ap_up:
                    //VisualStateManager.GoToState(this,Vs.infobuttonlpup.ToString(),false);
                    break;
                    case State.cp_enter:
                    //VisualStateManager.GoToState(this,Vs.infobuttonover.ToString(),false);
                    break;
                    case State.cp_leave:
                    //VisualStateManager.GoToState(this,Vs.infobuttonleave.ToString(),false);
                    break;
                    case State.cp_down:
                    VisualStateManager.GoToState(this,Vs.infobuttondown.ToString(),false);
                    break;
                    case State.cp_up:
                    this.OneClick();
                    VisualStateManager.GoToState(this,Vs.infobuttonup.ToString(),false);
                    break;
                    default:
                    break;
                }
                break;
                default:
                break;
            }
        }
    }
    public class InfoContent : IValueConverter {

        #region IValueConverter Members

        public object Convert(object value,Type targetType,object parameter,System.Globalization.CultureInfo culture) {
            var str = value.ToString();
            return str.Replace(";",Environment.NewLine);
        }

        public object ConvertBack(object value,Type targetType,object parameter,System.Globalization.CultureInfo culture) {
            throw new NotImplementedException();
        }

        #endregion
    }
}
